home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / db / esm-3.1 / esm-3 / usr / local / sm / src / serverlib / log / writeImage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-05  |  6.5 KB  |  276 lines

  1. /*
  2.  *   $RCSfile: writeImage.c,v $  
  3.  *   $Revision: 1.1.1.1 $  
  4.  *   $Date: 1996/05/04 21:55:49 $      
  5.  */ 
  6. /**********************************************************************
  7. * EXODUS Database Toolkit Software
  8. * Copyright (c) 1991 Computer Sciences Department, University of
  9. *                    Wisconsin -- Madison
  10. * All Rights Reserved.
  11. *
  12. * Permission to use, copy, modify and distribute this software and its
  13. * documentation is hereby granted, provided that both the copyright
  14. * notice and this permission notice appear in all copies of the
  15. * software, derivative works or modified versions, and any portions
  16. * thereof, and that both notices appear in supporting documentation.
  17. *
  18. * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
  19. * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.  
  20. * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
  21. * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  22. *
  23. * The EXODUS Project Group requests users of this software to return 
  24. * any improvements or extensions that they make to:
  25. *
  26. *   EXODUS Project Group 
  27. *     c/o David J. DeWitt and Michael J. Carey
  28. *   Computer Sciences Department
  29. *   University of Wisconsin -- Madison
  30. *   Madison, WI 53706
  31. *
  32. *     or exodus@cs.wisc.edu
  33. *
  34. * In addition, the EXODUS Project Group requests that users grant the 
  35. * Computer Sciences Department rights to redistribute these changes.
  36. **********************************************************************/
  37.  
  38. #include "sysdefs.h"
  39. #include "ess.h"
  40. #include "checking.h"
  41. #include "trace.h"
  42. #include "error.h"
  43. #include "list.h"
  44. #include "pool.h"
  45. #include "tid.h"
  46. #include "io.h"
  47. #include "lock.h"
  48. #include "object.h"
  49. #include "msgdefs.h"
  50. #include "thread.h"
  51. #include "semaphore.h"
  52. #include "latch.h"
  53. #include "link.h"
  54. #include "lsn.h"
  55. #include "bf.h"
  56. #include "volume.h"
  57. #include "openlog.h"
  58. #include "trans.h"
  59. #include "logrecs.h"
  60. #include "threadstate.h"
  61. #include "util_funcs.h"
  62. #include "log_intfuncs.h"
  63. #include "log_extfuncs.h"
  64. #include "log_globals.h"
  65. #include "thread_globals.h"
  66.  
  67.  
  68.  void
  69. writeImage (
  70.  
  71.     OPENLOG                *openLog,
  72.     LOGRECORDINFO        *logRecInfo,
  73.     int                    index,
  74.     LSNOFFSET            *recordLSN 
  75. )
  76. {
  77.     LSNOFFSET    tailLSN;
  78.     SHORTPID    tailPid;
  79.     int            total;
  80.     LSNOFFSET    offset;
  81.     int            size;
  82.     char        *image;
  83.     PAGEHASH    *tailBuffer;
  84.     int            count;
  85. #ifdef DEBUG
  86.     LSN                    debugLSN;
  87. #endif
  88.  
  89.     /*
  90.      *    put pointers in registers
  91.      */
  92.     size    = logRecInfo->imageSize[index];
  93.     image   = (char *) logRecInfo->imageData[index];
  94.     tailLSN = openLog->tailLSN;
  95.     tailPid = openLog->tailPid;
  96.  
  97.     TRPRINT(TR_LOG, TR_LEVEL_1, 
  98.         ("size:%d tailLSN %d", logRecInfo->imageSize[index], tailLSN));
  99.  
  100.     /*
  101.      *    place the image on successive pages
  102.      */
  103.     for (total = 0, count=0; total < size; total += count, image += count)    {
  104.  
  105.         /*
  106.          *    check to see if the offset is zero
  107.          *    we can come in with a zero offset or we can
  108.          *    generate a zero offset at the bottom of this loop
  109.          */
  110.         TRPRINT(TR_LOG, TR_LEVEL_2, ("total:%d count %d tailLSN %d, offset %d", 
  111.             total, count, tailLSN, LOG_PAGE_OFFSET(tailLSN, openLog)));
  112.  
  113.         if ((offset = LOG_PAGE_OFFSET(tailLSN, openLog)) == 0)    {
  114.  
  115.             /*
  116.              *    write the page header
  117.              */
  118.             writeLogPageHeader(openLog, tailPid);
  119.  
  120.             /*
  121.              *    increment the tail pointer
  122.              */
  123.             tailLSN += FIRST_LSN;
  124.             offset = FIRST_LSN;
  125.         }
  126.  
  127.         TRPRINT(TR_LOG, TR_LEVEL_2, ("offset:%d", offset));
  128.  
  129.         /*
  130.          *    save the buffer
  131.          */
  132.         tailBuffer = openLog->tailBuffer;
  133.  
  134.         /*
  135.          *    get the count of data to move
  136.          */
  137.         count = MIN((openLog->lastUsableByte - offset), (size - total));
  138.         TRPRINT(TR_LOG, TR_LEVEL_2, ("moving %d bytes", count));
  139.  
  140.         /*
  141.          *    copy the data
  142.          */
  143.         bcopy(image, tailBuffer->bufFrame + offset, count);
  144.  
  145.         /*
  146.          *    dirty the page
  147.          */
  148.         DIRTY_PAGE(tailBuffer);
  149.  
  150.         /*
  151.          *    check to see if the force mark is the first one
  152.          */
  153.         if (tailBuffer->firstMark == 0)    {
  154.  
  155.             /*
  156.              *    mark the first lsn
  157.              */
  158.             tailBuffer->firstMark = openLog->logRecordCount;
  159.             TRPRINT(TR_LOG, TR_LEVEL_2, ("firstMark:%d", tailBuffer->firstMark));
  160.         }
  161.  
  162.         /*
  163.          *    save the record number
  164.          */
  165.         tailBuffer->forceMark = openLog->logRecordCount;
  166.         TRPRINT(TR_LOG, TR_LEVEL_2, ("forceMark:%d", tailBuffer->forceMark));
  167.  
  168.         /*
  169.          *    increment the tail pointer
  170.          *    round up the pointer
  171.          */
  172.  
  173.         tailLSN += count;
  174.         tailLSN = ALIGN(tailLSN, 4);
  175.         TRPRINT(TR_LOG, TR_LEVEL_2, ("tailLSN:%d", tailLSN));
  176.  
  177.         /*
  178.          *    check to see if we advance to the next page
  179.          */
  180.         if (LOG_PAGE_OFFSET(tailLSN, openLog) == openLog->lastUsableByte)    {
  181.  
  182.             TRPRINT(TR_LOG, TR_LEVEL_2, ("advance to next page"));
  183.  
  184.             /*
  185.              *    check to see if the record offset is not null,
  186.              *    indicating that the record header is on this page
  187.              */
  188.             if (*recordLSN != NULL_LSN)    {
  189.  
  190.                 /*
  191.                  *    update the header with the address of the
  192.                  *    log record header
  193.                  */
  194.                 updateLogPageHeader(openLog, LOG_PAGE_OFFSET(*recordLSN, openLog));
  195.  
  196.                 /*
  197.                  *    null out the recordLSN
  198.                  */
  199.                 *recordLSN = NULL_LSN;
  200.             } else {
  201.  
  202.                 /*
  203.                  *  There is no log record header on this page, so
  204.                  *     just record the first usable byte on the page
  205.                  */
  206.                 updateLogPageHeader(openLog, FIRST_LSN);
  207.             }
  208.                 
  209.             /*
  210.              *    increment the tail page
  211.              */
  212.             tailPid = ((tailPid + 1) % openLog->filePages);
  213.             TRPRINT(TR_LOG, TR_LEVEL_2, ("tailPid:%d", tailPid));
  214.  
  215.             /*
  216.              *    check to see if the tail page is zero
  217.              */
  218.             if (tailPid == 0)    {
  219.  
  220.                 /*
  221.                  *    increment the wrap counter
  222.                  */
  223.                 openLog->wrapCount++;
  224.                 /* this confuses too many users:
  225.                 SM_ERROR(TYPE_LOG, esmLOGWRAPPED);
  226.                 */
  227.             }
  228.  
  229.             /*
  230.              *    recalculate the tail pointer
  231.              */
  232.             tailLSN = LOG_PAGE_TO_LSN(tailPid, openLog);
  233.         }
  234.     }
  235.  
  236. #ifdef DEBUG
  237.     /* make sure we don't overwrite important log records */
  238.     debugLSN.offset = tailLSN;
  239.     debugLSN.wrapCount = openLog->wrapCount-1;
  240.     SM_ASSERT(LEVEL_3, compareLSN(&debugLSN, &OldestDirtyPageLSN) < 0);
  241. #endif
  242.  
  243.     /*
  244.      *    See if this is the last image for the record and the
  245.      *    image does not completely fill page (ie. the log tail is not
  246.      *    on a new page).
  247.      */
  248.     if ( (index+1 == logRecInfo->imageCount) && !(LOG_PAGE_OFFSET(tailLSN, openLog) == 0) ) {
  249.  
  250.         /*
  251.          *    See if the record header is on this page. 
  252.          */
  253.         if (*recordLSN != NULL_LSN) {
  254.  
  255.             /*
  256.              *    update the header with the address of the
  257.              *    log record header
  258.              */
  259.             updateLogPageHeader(openLog, LOG_PAGE_OFFSET(*recordLSN, openLog));
  260.          } else {
  261.             
  262.             /*
  263.              *  There is no log record header on this page, so
  264.              *     just record the first usable byte on the page
  265.              */
  266.             updateLogPageHeader(openLog, FIRST_LSN);
  267.         }
  268.     }
  269.     /*
  270.      *    record the pointers
  271.      */
  272.     openLog->tailPid = tailPid;
  273.     openLog->tailLSN = tailLSN;
  274.     TRPRINT(TR_LOG, TR_LEVEL_2, ("tailPid:%d tailLSN:%d", tailPid, tailLSN));
  275. }
  276.